function irctest()
	local server = ircserver()

	while true do
		server:process()
	end
end

local ircserver_mt = {
	start = function(self)
		self.buffer = ""
		self:send_line("USER glip2 0 * lua_or_sth")
		self:send_line("NICK lua_or_sth")
	end,

	process = function(self)
		self.sock:flush()

		local more = self.sock:read()
		self.buffer = self.buffer .. more

		while true do

			local pos = self.buffer:find("[\r\n]")
			if not pos then break end

			local msg
			msg, self.buffer = parse_irc_message(self.buffer)
			if not msg then
				print("Invalid message: ", self.buffer)
				self.buffer = ""
				break
			end

			self:process_msg(msg)
		end
	end,

	process_msg = function(self, msg)
		if msg.cmd == "PING" then
			self:send_line("PONG :" .. msg[1])
		elseif msg.cmd == "001" then
			self:send_line("JOIN #liero")
		elseif msg.cmd == "PRIVMSG" then
			local channel = msg[1]
			local text = msg[2]
			if msg.nick and text == "hi lua_or_sth" then
				self:send_line("PRIVMSG " .. channel .. " :lo " .. msg.nick)
			end
		end
	end,

	send_line = function(self, line)
		print("## Sending: " .. line)
		self.sock:write(line .. "\r\n")
	end
}

ircserver_mt.__index = ircserver_mt

function ircserver()
	local sock = sockets.tcp_connect("se.quakenet.org", 6667)
	local server = setmetatable({sock = sock}, ircserver_mt)
	server:start()
	return server
end

function parse_irc_message(line)
	local prefix, command, i, next
	local nick, username, hostname

	i = 1
	prefix, next = line:match("^:([^ ]+) ()")
	if prefix then
		i = next
		nick, username, hostname = prefix:match("^(.*)!(.*)@(.*)$")
	end

	command, i = line:match("^([^ ]+)()", i)
	if not command then return nil, line end

	local msg = {
		cmd = command,
		prefix = prefix,
		nick = nick,
		username = username,
		hostname = hostname
	}
	local argn = 1

	while true do
		local param

		param, next = line:match("^ :([^\r\n]*)()", i)

		if param then -- Last parameter
			i = next
			msg[argn] = param
			break
		end

		param, next = line:match("^ ([^ \r\n]+)()", i)
		if not param then
			break
		end
		i = next

		msg[argn] = param
		argn = argn + 1
	end

	local ending = line:match("^[\r\n]+()", i)
	if ending then
		return msg, line:sub(ending) -- Cut off \r\n
	else
		return nil, line
	end
end

irctest()